#pragma once
#include "msgpack/object.hpp"
#include "msgpack/type.hpp"
#include "msgpack/pack.hpp"

#include "msgpack/v1/adaptor/cpp11/bitset.hpp"
//#include "msgpack/v1/adaptor/cpp11/timeval.hpp"

#define MSGPACK_DECLARE(my_class) \
namespace msgpack {\
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {\
namespace adaptor {\
template<>\
struct convert<my_class> {\
    msgpack::object const& operator()(msgpack::object const& o, my_class& v) const {\
		if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }\
		auto &&metas = v.Metas();\
		using TP = typename std::decay<decltype(metas)>::type;\
		msgpack::type::define_array_imp<TP, v.element_size>::unpack(o, metas);\
        return o;\
    }\
};\
template<>\
struct pack<my_class> {\
    template <typename Stream>\
    packer<Stream>& operator()(msgpack::packer<Stream>& o, my_class const& v) const {\
		o.pack_array(v.element_size);\
		const auto &&metas = v.Metas();\
		using TP = typename std::decay<decltype(metas)>::type;\
		msgpack::type::define_array_imp<TP, v.element_size>::pack(o, metas);\
        return o;\
    }\
};\
template <>\
struct object_with_zone<my_class> {\
    void operator()(msgpack::object::with_zone& o, my_class const& v) const {\
		o.type = msgpack::type::ARRAY;\
        o.via.array.size = v.element_size;\
        o.via.array.ptr = static_cast<msgpack::object*>(\
            o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size));\
		const auto &&metas = v.Metas();\
		using TP = typename std::decay<decltype(metas)>::type;\
		msgpack::type::define_array_imp<TP, v.element_size>::object(static_cast<msgpack::object*>(&o), o.zone, metas);\
    }\
};\
}\
}\
}
